package jmine.tec.di.wrapper;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

import jmine.tec.annotations.Unmodifiable;
import jmine.tec.utils.Tuple;
import jmine.tec.utils.UnmodifiableTuple;

/**
 * Faz o wrapping em um array
 * 
 * @author MarceloT
 */
@Unmodifiable
class ArrayWrapper extends AbstractWrapper implements Wrapper {

    private static final long serialVersionUID = 9111233463750150241L;

    /**
     * Wrapp varios valores
     * 
     * @param propertyKeys os nomes das propriedades
     * @param propertyValues os valores das propriedades
     * @param valueType o tipo de valor
     * @return Object
     */
    public Object wrap(Object[] propertyKeys, Object[] propertyValues, Class<?> valueType) {
        Object array = Array.newInstance(valueType, propertyValues.length);
        for (int i = 0; i < propertyValues.length; i++) {
            Object object = propertyValues[i];
            Array.set(array, i, object);
        }
        return array;
    }

    /**
     * Verifica se o tipo deste wrapper é compativel com o tipo de container passado
     * 
     * @param containerType Class
     * @return boolean
     */

    public boolean isTypeCompatible(Class<?> containerType) {
        return containerType.isArray();
    }

    /**
     * {@inheritDoc}
     */
    public boolean checkContainedType(Object resolved, Class<?> requiredComponentClass) {
        return requiredComponentClass.isAssignableFrom(resolved.getClass().getComponentType());
    }

    /**
     * {@inheritDoc}
     * 
     * @see jmine.tec.di.wrapper.Wrapper#collect(java.lang.Object, java.lang.String)
     */
    public List<Tuple<?, ?>> collect(Object resolved, String name) {
        final int n = Array.getLength(resolved);
        List<Tuple<?, ?>> list = new ArrayList<Tuple<?, ?>>(n);
        for (int i = 0; i < n; i++) {
            list.add(UnmodifiableTuple.newTuple(name, Array.get(resolved, i)));
        }
        return list;
    }

}
